# -*- coding: utf-8 -*-
"""
质量分级系统
提供多层次的质量控制和配置管理
"""

from enum import Enum
from typing import Dict, Any, Optional, List
from pathlib import Path
import json
import logging

logger = logging.getLogger(__name__)


class QualityLevel(Enum):
    """质量级别枚举"""
    PREVIEW = "preview"  # 预览质量（快速）
    STANDARD = "standard"  # 标准质量
    HIGH = "high"  # 高质量
    ULTRA = "ultra"  # 超高质量


class QualityConfig:
    """质量配置类"""

    # 质量级别配置
    QUALITY_PRESETS = {
        QualityLevel.PREVIEW: {
            "name": "预览质量",
            "description": "快速预览，适合开发阶段",
            "video": {
                "resolution": (1280, 720),
                "frame_rate": 15,
                "bitrate": "2000k",
                "quality": "low",
            },
            "image": {
                "resolution": (1280, 720),
                "dpi": 72,
            },
            "audio": {
                "sample_rate": 22050,
                "bitrate": "128k",
                "channels": 1,
            },
            "render": {
                "disable_caching": False,
                "max_workers": 2,
                "timeout": 300,
            },
            "output": {
                "format": "mp4",
                "compression": "fast",
            },
        },
        QualityLevel.STANDARD: {
            "name": "标准质量",
            "description": "平衡质量与速度，适合一般用途",
            "video": {
                "resolution": (1920, 1080),
                "frame_rate": 30,
                "bitrate": "5000k",
                "quality": "medium",
            },
            "image": {
                "resolution": (1920, 1080),
                "dpi": 96,
            },
            "audio": {
                "sample_rate": 44100,
                "bitrate": "192k",
                "channels": 2,
            },
            "render": {
                "disable_caching": False,
                "max_workers": 4,
                "timeout": 600,
            },
            "output": {
                "format": "mp4",
                "compression": "balanced",
            },
        },
        QualityLevel.HIGH: {
            "name": "高质量",
            "description": "高质量输出，适合正式演示",
            "video": {
                "resolution": (1920, 1080),
                "frame_rate": 30,
                "bitrate": "8000k",
                "quality": "high",
            },
            "image": {
                "resolution": (1920, 1080),
                "dpi": 150,
            },
            "audio": {
                "sample_rate": 48000,
                "bitrate": "320k",
                "channels": 2,
            },
            "render": {
                "disable_caching": False,
                "max_workers": 6,
                "timeout": 1200,
            },
            "output": {
                "format": "mp4",
                "compression": "high_quality",
            },
        },
        QualityLevel.ULTRA: {
            "name": "超高质量",
            "description": "最高质量，适合商业制作",
            "video": {
                "resolution": (2560, 1440),
                "frame_rate": 60,
                "bitrate": "15000k",
                "quality": "ultra",
            },
            "image": {
                "resolution": (2560, 1440),
                "dpi": 300,
            },
            "audio": {
                "sample_rate": 48000,
                "bitrate": "320k",
                "channels": 2,
            },
            "render": {
                "disable_caching": True,
                "max_workers": 8,
                "timeout": 3600,
            },
            "output": {
                "format": "mp4",
                "compression": "lossless",
            },
        },
    }

    def __init__(self, quality: QualityLevel):
        """
        初始化质量配置

        Args:
            quality: 质量级别
        """
        self.quality = quality
        self.config = self.QUALITY_PRESETS[quality].copy()

    def get_video_config(self) -> Dict[str, Any]:
        """获取视频配置"""
        return self.config["video"]

    def get_image_config(self) -> Dict[str, Any]:
        """获取图片配置"""
        return self.config["image"]

    def get_audio_config(self) -> Dict[str, Any]:
        """获取音频配置"""
        return self.config["audio"]

    def get_render_config(self) -> Dict[str, Any]:
        """获取渲染配置"""
        return self.config["render"]

    def get_output_config(self) -> Dict[str, Any]:
        """获取输出配置"""
        return self.config["output"]

    def update_config(self, config_type: str, updates: Dict[str, Any]):
        """
        更新配置

        Args:
            config_type: 配置类型（video/image/audio/render/output）
            updates: 更新项
        """
        if config_type in self.config:
            self.config[config_type].update(updates)

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "quality": self.quality.value,
            "name": self.config["name"],
            "description": self.config["description"],
            "config": self.config,
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "QualityConfig":
        """从字典创建"""
        quality = QualityLevel(data["quality"])
        return cls(quality)

    def __str__(self) -> str:
        return f"{self.config['name']} ({self.quality.value})"

    def __repr__(self) -> str:
        return f"QualityConfig(quality={self.quality.value})"


class QualityValidator:
    """质量配置验证器"""

    @staticmethod
    def validate_video_config(config: Dict[str, Any]) -> tuple[bool, list[str]]:
        """
        验证视频配置

        Args:
            config: 视频配置

        Returns:
            (是否有效, 错误列表)
        """
        errors = []

        # 检查分辨率
        resolution = config.get("resolution")
        if not resolution or len(resolution) != 2:
            errors.append("Invalid resolution: must be a tuple of (width, height)")
        else:
            width, height = resolution
            if width < 320 or height < 240:
                errors.append("Resolution too low: minimum 320x240")
            if width > 7680 or height > 4320:
                errors.append("Resolution too high: maximum 7680x4320 (8K)")

        # 检查帧率
        frame_rate = config.get("frame_rate")
        if not isinstance(frame_rate, int) or frame_rate < 1 or frame_rate > 120:
            errors.append("Invalid frame_rate: must be between 1 and 120")

        # 检查码率
        bitrate = config.get("bitrate")
        if bitrate and not isinstance(bitrate, str):
            errors.append("Invalid bitrate: must be a string like '5000k'")

        return len(errors) == 0, errors

    @staticmethod
    def validate_audio_config(config: Dict[str, Any]) -> tuple[bool, list[str]]:
        """
        验证音频配置

        Args:
            config: 音频配置

        Returns:
            (是否有效, 错误列表)
        """
        errors = []

        # 检查采样率
        sample_rate = config.get("sample_rate")
        valid_rates = [8000, 16000, 22050, 44100, 48000, 96000, 192000]
        if sample_rate not in valid_rates:
            errors.append(f"Invalid sample_rate: must be one of {valid_rates}")

        # 检查码率
        bitrate = config.get("bitrate")
        valid_bitrates = ["64k", "96k", "128k", "192k", "256k", "320k"]
        if bitrate not in valid_bitrates:
            errors.append(f"Invalid bitrate: must be one of {valid_bitrates}")

        # 检查声道数
        channels = config.get("channels")
        if channels not in [1, 2, 6, 8]:
            errors.append("Invalid channels: must be 1, 2, 6, or 8")

        return len(errors) == 0, errors

    @staticmethod
    def validate_render_config(config: Dict[str, Any]) -> tuple[bool, list[str]]:
        """
        验证渲染配置

        Args:
            config: 渲染配置

        Returns:
            (是否有效, 错误列表)
        """
        errors = []

        # 检查最大工作进程数
        max_workers = config.get("max_workers")
        if not isinstance(max_workers, int) or max_workers < 1:
            errors.append("Invalid max_workers: must be a positive integer")

        # 检查超时时间
        timeout = config.get("timeout")
        if not isinstance(timeout, int) or timeout < 60:
            errors.append("Invalid timeout: must be at least 60 seconds")

        return len(errors) == 0, errors

    def validate(self, quality_config: QualityConfig) -> tuple[bool, list[str]]:
        """
        验证完整配置

        Args:
            quality_config: 质量配置

        Returns:
            (是否有效, 错误列表)
        """
        errors = []

        # 验证各个部分
        is_valid, video_errors = self.validate_video_config(
            quality_config.config.get("video", {})
        )
        if not is_valid:
            errors.extend(["Video: " + e for e in video_errors])

        is_valid, audio_errors = self.validate_audio_config(
            quality_config.config.get("audio", {})
        )
        if not is_valid:
            errors.extend(["Audio: " + e for e in audio_errors])

        is_valid, render_errors = self.validate_render_config(
            quality_config.config.get("render", {})
        )
        if not is_valid:
            errors.extend(["Render: " + e for e in render_errors])

        return len(errors) == 0, errors


class QualityReporter:
    """质量报告生成器"""

    @staticmethod
    def generate_report(quality_config: QualityConfig) -> Dict[str, Any]:
        """
        生成质量报告

        Args:
            quality_config: 质量配置

        Returns:
            报告字典
        """
        report = {
            "quality_level": quality_config.quality.value,
            "quality_name": quality_config.config["name"],
            "description": quality_config.config["description"],
            "video": quality_config.get_video_config(),
            "audio": quality_config.get_audio_config(),
            "render": quality_config.get_render_config(),
            "estimated_stats": QualityReporter._estimate_stats(quality_config),
        }

        # 验证配置
        validator = QualityValidator()
        is_valid, errors = validator.validate(quality_config)
        report["validation"] = {
            "is_valid": is_valid,
            "errors": errors,
        }

        return report

    @staticmethod
    def _estimate_stats(quality_config: QualityConfig) -> Dict[str, Any]:
        """
        估算质量相关统计

        Args:
            quality_config: 质量配置

        Returns:
            统计信息
        """
        video_config = quality_config.get_video_config()
        resolution = video_config["resolution"]
        frame_rate = video_config["frame_rate"]

        # 估算数据量（假设100秒视频）
        duration_seconds = 100
        pixels = resolution[0] * resolution[1]
        total_pixels = pixels * frame_rate * duration_seconds

        # 估算文件大小（粗略计算）
        estimated_size_mb = (total_pixels * 3) / (8 * 1024 * 1024)  # RGB，无压缩

        return {
            "resolution": f"{resolution[0]}x{resolution[1]}",
            "frame_rate": f"{frame_rate} fps",
            "total_pixels": total_pixels,
            "estimated_size_mb": round(estimated_size_mb, 2),
            "estimated_render_time_minutes": round(estimated_size_mb / 10, 1),  # 粗略估算
        }

    @staticmethod
    def save_report(report: Dict[str, Any], output_path: Path):
        """
        保存报告

        Args:
            report: 报告字典
            output_path: 输出路径
        """
        output_path.parent.mkdir(parents=True, exist_ok=True)

        with open(output_path, "w", encoding="utf-8") as f:
            json.dump(report, f, indent=2, ensure_ascii=False)

        logger.info(f"Quality report saved to: {output_path}")


class QualityManager:
    """质量管理器"""

    def __init__(self):
        """初始化质量管理器"""
        self.current_quality = QualityLevel.STANDARD
        self.config = QualityConfig(self.current_quality)

    def set_quality(self, quality: QualityLevel):
        """
        设置质量级别

        Args:
            quality: 质量级别
        """
        self.current_quality = quality
        self.config = QualityConfig(quality)
        logger.info(f"Quality set to: {quality.value}")

    def get_video_config(self) -> Dict[str, Any]:
        """获取视频配置"""
        return self.config.get_video_config()

    def get_audio_config(self) -> Dict[str, Any]:
        """获取音频配置"""
        return self.config.get_audio_config()

    def get_render_config(self) -> Dict[str, Any]:
        """获取渲染配置"""
        return self.config.get_render_config()

    def get_output_config(self) -> Dict[str, Any]:
        """获取输出配置"""
        return self.config.get_output_config()

    def update_config(self, config_type: str, updates: Dict[str, Any]):
        """
        更新配置

        Args:
            config_type: 配置类型
            updates: 更新项
        """
        # 重新创建配置以确保更新生效
        config_dict = self.config.to_dict()
        new_config = QualityConfig.from_dict(config_dict)
        new_config.update_config(config_type, updates)

        self.config = new_config

    def generate_report(self, output_path: Optional[Path] = None) -> Dict[str, Any]:
        """
        生成质量报告

        Args:
            output_path: 输出路径（可选）

        Returns:
            报告字典
        """
        report = QualityReporter.generate_report(self.config)

        if output_path:
            QualityReporter.save_report(report, output_path)

        return report

    def auto_select_quality(
        self,
        target_duration: float,
        hardware_level: str = "medium",
    ) -> QualityLevel:
        """
        自动选择质量级别

        Args:
            target_duration: 目标时长（秒）
            hardware_level: 硬件水平（low/medium/high）

        Returns:
            建议的质量级别
        """
        # 基于硬件和时长选择
        if hardware_level == "low" or target_duration > 300:  # 5分钟+
            return QualityLevel.PREVIEW
        elif target_duration > 60:  # 1分钟+
            return QualityLevel.STANDARD
        elif hardware_level == "high":
            return QualityLevel.ULTRA
        else:
            return QualityLevel.HIGH
